#pragma once
#include "Runtime/BattleFirePrefix.h"
#include "Runtime/Base/Object.h"
#include "Runtime/Utils/SmartPtr.h"
namespace Alice{
    class Event : public Object{
    public:
        std::mutex mMutex;
        std::condition_variable mConditionVariable;
        Event()
        {
        }
        ~Event()
        {
        }
        virtual void TriggerOne()
        {
            std::unique_lock<std::mutex> UniqueLock(mMutex);
            mConditionVariable.notify_one();
        }
        virtual void TriggerAll()
        {
            std::unique_lock<std::mutex> UniqueLock(mMutex);
            mConditionVariable.notify_all();
        }
        virtual bool Wait( uint32 WaitTime = (uint32)-1)
        {
            std::unique_lock<std::mutex> UniqueLock(mMutex);
            return std::cv_status::timeout != mConditionVariable.wait_for(UniqueLock,std::chrono::seconds(WaitTime));
        }
    };
    class ScopedEvent
    {
    public:
        ScopedEvent()
        {
            mEvent=new Event;
        }
        ~ScopedEvent()
        {
            if (mEvent.mPtr!=nullptr)
            {
                mEvent->Wait();
                mEvent->release();
            }
        }
        void Trigger()
        {
            mEvent->TriggerAll();
        }
        bool IsReady()
        {
            if (mEvent.mPtr!=nullptr)
            {
                if ( mEvent->Wait(1) )
                {
                    mEvent->release();
                    mEvent = nullptr;
                    return true;
                }
                return false;
            }
            return true;
        }
        SmartPtr<Event>& Get()
        {
            return mEvent;
        }

    private:
        SmartPtr<Event> mEvent;
    };
}